import os
import json

# tagPath = './ypy2'
tagPath = './tag'
# outPath = './fu.result.out.zip.0.55009.初赛模型.v0.1.0完全js匹配'
outPath = './out'

noMatchHandDic = {}

def mMax(n1, n2):
    if (n1 > n2):
        return n1
    else:
        return n2
def mMin(n1, n2):
    if (n1 < n2):
        return n1
    else:
        return n2
# 计算两个标记之间的重合比例
def getP(sign1, sign2):
    mixAreaX = mMax(sign1['x'], sign2['x'])
    mixAreaY = mMax(sign1['y'], sign2['y'])
    mixAreaX2 = mMin(sign1['x'] + sign1['w'], sign2['x'] + sign2['w'])
    mixAreaY2 = mMin(sign1['y'] + sign1['h'], sign2['y'] + sign2['h'])
    sign1Area = sign1['w'] * sign1['h']
    sign2Area = sign2['w'] * sign2['h']
    mixAreaW = mixAreaX2 - mixAreaX
    mixAreaH = mixAreaY2 - mixAreaY
    # print(mixAreaW, mixAreaH)
    if (mixAreaW > 0 and mixAreaH > 0):
        mixArea = mixAreaW * mixAreaH
        return mixArea / (sign1Area + sign2Area - mixArea)
    else:
        return 0
    
# 测试p函数
# p = getP({'x':0,'y':0,'w':2,'h':2},{'x':0,'y':0,'w':1,'h':1}) 
# p = getP({'x':2,'y':0,'w':2,'h':2},{'x':0,'y':0,'w':1,'h':1}) 
# print(p)
def getSign(signId, signs):
    for sign in signs:
        if sign['sign_id'] == signId:
            return sign

# 计算一堆标记之间的重合比例
def getSignF1Score(tagSigns, outSigns):
    sumP = 0 # 总重合比例
    sumC = 0 # 总数
    for tagSign in tagSigns:
        for outSign in outSigns:
            if (tagSign['pic_id'] == outSign['pic_id']):
                p = getP(tagSign, outSign)
                print(tagSign['pic_id'], p)
                if (p > .5):
                    sumP = sumP + p
                    sumC = sumC + 1
    if sumC == 0:
        return 0
    process = sumC / len(outSigns)
    recall = sumC / len(tagSigns)
    f1Score = 2 * process * recall / (process + recall)
    # print(sumP, sumC, len(tagSigns))
    return f1Score

def getF1Score(tagMatches, outMatches, tagSigns, outSigns):
    TP = 0
    W = 0
    for tagMatch in tagMatches:
        # print(tagMatch)
        _TP = 0
        for outMatch in outMatches:
            __TP = 0
            tagSign = getSign(tagMatch['sign_id'], tagSigns)
            tagSign2 = getSign(tagMatch['match_sign_id'], tagSigns)
            outSign = getSign(outMatch['sign_id'], outSigns)
            outSign2 = getSign(outMatch['match_sign_id'], outSigns)
            if (tagSign and tagSign2 and outSign and outSign2 and tagSign['type'] == tagSign2['type']):
                if (tagSign['pic_id'] == outSign['pic_id']):
                    if (tagSign2['pic_id'] == outSign2['pic_id']):
                        if getP(tagSign, outSign)>.5 and tagSign['type'] == outSign['type']\
                            and getP(tagSign2, outSign2) and tagSign2['type'] == outSign2['type']:
                            outMatch['m'] = 1
                            tagSign['m'] = tagSign2['m'] = outSign['m'] = outSign2['m'] = 1
                            TP = TP + 1
                            # _TP = _TP + 1
                            # __TP = __TP + 1
                            break
                if (tagSign['pic_id'] == outSign2['pic_id']):
                    if (tagSign2['pic_id'] == outSign['pic_id']):
                        if getP(tagSign, outSign2)>.5 and tagSign['type'] == outSign2['type']\
                            and getP(tagSign2, outSign) and tagSign2['type'] == outSign['type']:
                            outMatch['m'] = 1
                            tagSign['m'] = tagSign2['m'] = outSign['m'] = outSign2['m'] = 1
                            TP = TP + 1
                            # _TP = _TP + 1
                            # __TP = __TP + 1
                            break
            if (tagSign and not tagSign2 and outSign and not outSign2 and tagSign['type'] == outSign['type']):
                if (tagSign['pic_id'] == outSign['pic_id']):
                    if getP(tagSign, outSign)>.5 and tagSign['type'] == outSign['type']:
                        outMatch['m'] = 1
                        tagSign['m'] = outSign['m'] = 1
                        TP = TP + 1
                        # _TP = _TP + 1
                        # __TP = __TP + 1
                        break
                    if getP(tagSign, outSign)<.5 and tagSign['type'] == outSign['type']:
                        outMatch['nm'] = 1
                        tagSign['nm'] = outSign['nm'] = 1
                        W = W +1
            # if __TP > 0:
            #     print(_TP, tagMatch)
            #     print(tagSign)
            #     print(tagSign2)
            #     print(outSign)
            #     print(outSign2)
    print(W, len(tagMatches), len(outMatches))
    if (TP == 0):
        return 0
    process = TP / len(tagMatches)
    recall = TP / len(outMatches)
    return 2 * process * recall / (process + recall)

def getAvgF1Score(tagDirPath, outDirPath):
    tagFiles = os.listdir(tagDirPath)
    outFiles = os.listdir(outDirPath)
    count = 0
    sumF1Score = 0
    outNoMatchedTagDic = {}
    sumC = 0
    sumA = 0
    if len(tagFiles) != len(outFiles) and len(tagFiles) != 0:
        print('目标文件夹文件数目不一致')
    else:
        for tagFile in tagFiles:
            for outFile in outFiles:
                if (tagFile == outFile):
                    with open(tagDirPath + '/' + tagFile, 'r') as f:
                        tagDic = json.load(f)
                    with open(outDirPath + '/' + outFile, 'r') as f:
                        outDic = json.load(f)
                    f1Score = getF1Score(tagDic['match'], outDic['match'], tagDic['signs'], outDic['signs'])
                    # f1Score = getSignF1Score(tagDic['signs'], outDic['signs'])
                    print(tagFile)
                    # 获取原始中没找到的
                    tagMatchs = tagDic['match']
                    tagSigns = tagDic['signs']
                    c = 0 # 匹配到的
                    oc = 0
                    a = 0 # 未匹配到的
                    for tagMatch in tagMatchs:
                        tagSign = getSign(tagMatch['sign_id'], tagSigns)
                        tagSign2 = getSign(tagMatch['match_sign_id'], tagSigns)
                        if 'm' in tagSign:
                            c = c+1
                        else:
                            a = a+1
                            ca = c+a
                            outNoMatchedTagDic[tagFile + '-' + str(c+a)] = {
                                "sign_id":tagMatch['sign_id'],
                                "match_sign_id":tagMatch['match_sign_id'],
                                "a":tagSign
                            }
                            if (tagSign2):
                                outNoMatchedTagDic[tagFile + '-' + str(c+a)]['b'] = tagSign2
                        
                    print('c,a', c,a)
                    sumC = sumC + c
                    sumA = sumA + a
                    print('sumC,sumA', sumC,sumA)
                    # return 0
                    sumF1Score = sumF1Score + f1Score
                    count = count +1
        avgF1Score = sumF1Score / count
        json_str = json.dumps(outNoMatchedTagDic, ensure_ascii=False, indent=0) # 缩进4字符
        with open('noMatch.handDic.json', 'w') as json_file:
            json_file.write(json_str)
        return avgF1Score

# 测试 getF1Score
# files = os.listdir(tagPath)
# with open(tagPath + '/' + files[0], 'r') as f:
#     s1 = json.load(f)
# with open(outPath + '/' + files[0], 'r') as f:
#     s2 = json.load(f)
# # JSON文件有3个key：["group", "signs", "match"]
# # print(s1['signs'])
# # f1Score = getSignF1Score(s1['signs'], s2['signs'])

# # s1为标签，s2为预测，返回f1Score
# f1Score = getF1Score(s1['match'], s2['match'], s1['signs'], s2['signs'])
# print(f1Score)

# 填写标签路径 和输出路径
avgF1Score = getAvgF1Score(tagPath, outPath)
print('avgF1Score:', avgF1Score)